package screen;

import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import java.util.Vector;

import localization.alarmclockResource;
import net.rim.device.api.i18n.ResourceBundle;
import net.rim.device.api.i18n.SimpleDateFormat;
import net.rim.device.api.system.Characters;
import net.rim.device.api.system.PersistentObject;
import net.rim.device.api.system.PersistentStore;
import net.rim.device.api.system.RealtimeClockListener;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.CheckboxField;
import net.rim.device.api.ui.component.DateField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.EditField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.NullField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.util.DateTimeUtilities;
import net.rim.device.api.util.MathUtilities;
import code.BirthdayReminderSettings;
import code.Config;
import code.LunarCalendar;
import ctrl.ForegroundManager;
import ctrl.ListStyleButtonField;
import ctrl.ListStyleButtonSet;
import ctrl.RoundRectFieldManager;

public class NewBirthdayReminderScreen extends MainScreen implements RealtimeClockListener, FieldChangeListener, alarmclockResource
{
	private ForegroundManager _foreground=new ForegroundManager(0);
	private ListStyleButtonSet _buttonSet=new ListStyleButtonSet();
	private EditField _birthdayName;
	private ListStyleButtonField link=new ListStyleButtonField("", "", getResString(TIPS_REMAINING), "");;
	private CheckboxField _usingLunar;
	private DateField _birthdayDate;

	private int _index;
	private boolean editMode;
	private boolean _isModified=false;
	
	private static PersistentObject _store;
	private static Vector _data=new Vector();
	private static ResourceBundle _resources = ResourceBundle.getBundle(BUNDLE_ID, BUNDLE_NAME);
	
	public NewBirthdayReminderScreen()
	{
		super(USE_ALL_WIDTH | NO_VERTICAL_SCROLL);
	
		setTitle(getResString(TITLE_ADD_NEW_BIRTHDAY_REMINDER));
		initUI();
		
    	UiApplication.getUiApplication().invokeLater(new Runnable()
    	{
			public void run() {
				_birthdayName.setDirty(true);		
			}
		});
    	
    	_index=-1;
    	editMode=false;
	}
	
	public NewBirthdayReminderScreen(BirthdayReminderSettings item, int index)
	{
		super(USE_ALL_WIDTH | NO_VERTICAL_SCROLL);
		
		setTitle(getResString(TITLE_EDIT_BIRTHDAYREMINDER));
		initUI();
		
    	UiApplication.getUiApplication().invokeLater(new Runnable()
    	{
			public void run() {
				_birthdayDate.setDirty(false);
				_usingLunar.setDirty(false);
			}
		});

		_birthdayName.setText(item.getBirthdayName());
		_birthdayDate.setDate(item.getBirthdayDate());
		_usingLunar.setChecked(item.getIsUsingLunar());
		
    	_index=index;
    	editMode=true;
	}
	
	private void initUI()
	{
		RoundRectFieldManager vfm1=new RoundRectFieldManager(), vfm2=new RoundRectFieldManager();

		LabelField settings=new LabelField(getResString(LABEL_TITLE_SETTINGS), USE_ALL_WIDTH | LabelField.ELLIPSIS) {
    		protected void paint(Graphics g) {g.setColor(Color.DARKGRAY); super.paint(g);}};
    	settings.setFont(Config.FONT_SETTINGS);
    	
    	_birthdayName=new EditField(getResString(LABEL_CAPTION_SHOW_NAME), getResString(LABEL_SHOW_CONTENT_NAME), 14, EDITABLE | USE_ALL_WIDTH | NON_SPELLCHECKABLE);

    	Calendar calendar=Calendar.getInstance(TimeZone.getDefault());
    	calendar.setTime(new Date(System.currentTimeMillis()));
    	calendar.set(Calendar.HOUR_OF_DAY, 0);
    	calendar.set(Calendar.MINUTE, 0);
    	calendar.set(Calendar.SECOND, 0);
    	calendar.set(Calendar.MILLISECOND, 0);
    	_birthdayDate=new DateField(getResString(LABEL_CAPTION_DATE_OF_BIRTH), calendar.getTime().getTime(), DateField.DATE);
    	
		_usingLunar=new CheckboxField(getResString(LABEL_CAPTION_USE_LUNAR_REMIND), true, 134217728 | USE_ALL_WIDTH);
    	
		vfm1.add(settings);
    	vfm1.add(new SeparatorField());
    	vfm1.add(_birthdayName);
    	vfm1.add(_birthdayDate);
    	vfm1.add(_usingLunar);
		vfm1.setMargin(5,5,5,5);
		vfm1.setPadding(3,5,5,5);

    	_buttonSet.add(link);
		
		LabelField sample=new LabelField(getResString(LABEL_TITLE_SAMPLE), USE_ALL_WIDTH | LabelField.ELLIPSIS) {
    		protected void paint(Graphics g) {g.setColor(Color.DARKGRAY); super.paint(g);}};
    	sample.setFont(Config.FONT_SETTINGS);
    	
    	vfm2.add(sample);
    	vfm2.add(new SeparatorField());
    	vfm2.add(_buttonSet);
		vfm2.setMargin(5,5,5,5);
		vfm2.setPadding(3,5,5,5);
		
    	_foreground.add(vfm1);
		_foreground.add(new NullField(NON_FOCUSABLE));
		_foreground.add(new NullField(NON_FOCUSABLE));
    	_foreground.add(vfm2);
    	//_foreground.add(vfm3);
    	//_foreground.add(vfm4);
    	
		add(_foreground);
		
		clockUpdated();
		UiApplication.getUiApplication().addRealtimeClockListener(this);
		
		_birthdayName.setChangeListener(this);
		_birthdayDate.setChangeListener(this);
		_usingLunar.setChangeListener(this);
	}
		
	private String getLunar(int year, int month, int day)
	{
	    long[] l = LunarCalendar.Lunar(year, month, day);
	    
	    String month1 = (int) l[3]==1 ? "闰 " : "";
	    switch((int) l[1])
	    {
	      	case 1:month1+="一月";break;
	      	case 2:month1+="二月";break;
	      	case 3:month1+="三月";break;
	      	case 4:month1+="四月";break;
	      	case 5:month1+="五月";break;
	      	case 6:month1+="六月";break;
	      	case 7:month1+="七月";break;
	      	case 8:month1+="八月";break;
	      	case 9:month1+="九月";break;
	      	case 10:month1+="十月";break;
	      	case 11:month1+="冬月";break;
	      	case 12:month1+="腊月";break;
	    }
	    
	    return " (" + month1 + LunarCalendar.cDay((int)(l[2])) + ")";
	}

	public boolean isModified()
	{
		return _isModified;
	}
	
	private String booleanToString(boolean bool)
	{
		return bool ? "1" : "0";
	}
	
    private String getResString(int key)
	{
		return _resources.getString(key);
	}
    
    static
   	{
   		_store=PersistentStore.getPersistentObject(0xaa041103a4a17b66L); //blackberry_alarmclock_worldclock_settings_id
   		
   		synchronized(_store)
   		{
   			if(_store.getContents()==null)
   			{
   				_store.setContents(new Vector());
   				_store.forceCommit();
   			}
   		}
   		
   		try {
   			_data=new Vector();
   			_data=(Vector) _store.getContents();
   		} catch (final Exception e) {}
   	}
    
    protected boolean keyChar(char c, int status, int time)
    {
    	if(_birthdayName.isFocus() && _birthdayName.getText().equals(getResString(LABEL_SHOW_CONTENT_NAME)) && c==Characters.BACKSPACE)
    	{
    		_birthdayName.setText("");
    		_birthdayName.setDirty(true);
    		
    		return true;
    	}
    	
    	return super.keyChar(c, status, time);
    }
    
	protected boolean onSave()
	{
		if(_birthdayName.getText().equals(""))
		{
			Dialog.alert(getResString(DIALOG_TIPS_NAME_NOT_NONE));
			_birthdayName.setFocus();
			
			return false;
		}
		
		BirthdayReminderSettings settings=new BirthdayReminderSettings();
		Calendar calendar=Calendar.getInstance(TimeZone.getDefault());
		settings.setBirthdayName(_birthdayName.getText());

		calendar.setTime(new Date(_birthdayDate.getDate()));
		//calendar.set(Calendar.HOUR, 0);
		//calendar.set(Calendar.MINUTE, 0);
		//calendar.set(Calendar.SECOND, 0);
		//calendar.set(Calendar.MILLISECOND, 0);
		if(calendar.get(Calendar.YEAR)<1901) {calendar.set(Calendar.YEAR, 1901); _birthdayDate.setDate(calendar.getTime());}
		settings.setBirthdayDate(String.valueOf(calendar.getTime().getTime()));
		settings.setIsUsingLunar(booleanToString(_usingLunar.getChecked()));
		
		if(editMode)
		{
			int iCount=0;
			
			for(int i=0; i<_data.size(); i++)
			{
				if(_data.elementAt(i) instanceof BirthdayReminderSettings)
				{
					if(iCount==_index)
					{
						_data.setElementAt(settings, i);
						
						i=_data.size()+1;
					}
					
					iCount+=1;
				}
			}
		} else {
			_data.addElement(settings);	
		}
		
		synchronized(_store)
		{
			_store.setContents(_data);
			_store.commit();
		}
		
		_isModified=true;
		
		return true;
	}

	public void clockUpdated()
	{
	    
	    if(_birthdayDate.getDate()>System.currentTimeMillis())
	    {
	    	Calendar calendar=Calendar.getInstance(TimeZone.getDefault());
	    	
	    	calendar.setTime(new Date(System.currentTimeMillis()));
	    	calendar.set(Calendar.HOUR_OF_DAY, 0);
	    	calendar.set(Calendar.MINUTE, 0);
	    	calendar.set(Calendar.SECOND, 0);
	    	calendar.set(Calendar.MILLISECOND, 0);
	    	_birthdayDate.setDate(calendar.getTime());
	    	
	    	Dialog.alert(getResString(DIALOG_TIPS_BIRTHDAY_MORE_THAN_TODAY));
	    }

	    Calendar calendarBirthday=Calendar.getInstance(TimeZone.getDefault());
	    Calendar calendarToday=Calendar.getInstance(TimeZone.getDefault());
	    Calendar calendarBirthdayTemp=Calendar.getInstance(TimeZone.getDefault());
	    Calendar calendarTodayTemp=Calendar.getInstance(TimeZone.getDefault());
	    
	    calendarBirthday.setTime(new Date(_birthdayDate.getDate()));
	    
	    calendarToday.setTime(new Date());
	    calendarToday.set(Calendar.HOUR, 0);
	    calendarToday.set(Calendar.MINUTE, 0);
	    calendarToday.set(Calendar.SECOND, 0);
	    calendarToday.set(Calendar.MILLISECOND, 0);
	    
	    if(calendarBirthday.get(Calendar.YEAR)<1901) {calendarBirthday.set(Calendar.YEAR, 1901);}
	    calendarBirthdayTemp.setTime(calendarBirthday.getTime());
	    calendarTodayTemp.setTime(calendarToday.getTime());
	    
	    calendarBirthdayTemp.set(Calendar.YEAR, calendarToday.get(Calendar.YEAR));

	    String lunarDay="";
		if(_usingLunar.getChecked())
		{
			
		    int birthYear = calendarBirthday.get(Calendar.YEAR);
		    int birthMonth = calendarBirthday.get(Calendar.MONTH)+1;
		    int birthDay = calendarBirthday.get(Calendar.DAY_OF_MONTH);
		    long[] lunar=LunarCalendar.Lunar(birthYear, birthMonth, birthDay);
		    long[] lunarTemp=new long[4];
		    int count=-1;
		    boolean gotIt=false;
		    
		    lunarDay=getLunar(birthYear, birthMonth, birthDay);
		    
		    while(!gotIt)
		    {
			    birthYear = calendarTodayTemp.get(Calendar.YEAR);
			    birthMonth = calendarTodayTemp.get(Calendar.MONTH)+1;
			    birthDay = calendarTodayTemp.get(Calendar.DAY_OF_MONTH);
			    lunarTemp=LunarCalendar.Lunar(birthYear, birthMonth, birthDay);
			    
			    if(lunarTemp[1]==lunar[1] && lunarTemp[2]==lunar[2])
			    {
			    	gotIt=true;
			    }
			    
			    count+=1;
			    calendarTodayTemp.set(Calendar.DAY_OF_MONTH, calendarTodayTemp.get(Calendar.DAY_OF_MONTH)+1);
		    }
		    
	    	birthYear = calendarToday.get(Calendar.YEAR);
	    	birthMonth = calendarToday.get(Calendar.MONTH)+1;
	    	birthDay = calendarToday.get(Calendar.DAY_OF_MONTH);
	    	lunarTemp=LunarCalendar.Lunar(birthYear, birthMonth, birthDay);

	    	boolean overDay=false;
	    	if(lunarTemp[1]>lunar[1] || (lunarTemp[1]==lunar[1] && lunarTemp[2]>=lunar[2])) {overDay=true;}

		    int age=calendarToday.get(Calendar.YEAR)-calendarBirthday.get(Calendar.YEAR)-(overDay ? 0 : 1);
		    link.setRemainingDaysText(count+getResString(TIPS_REMAINING_DAYS));
		    link.setTitleText(_birthdayName.getText() + " (" + age + ")");
		} else {
		    long remainingDays=MathUtilities.round((double) (calendarBirthdayTemp.getTime().getTime()-calendarToday.getTime().getTime())/DateTimeUtilities.ONEDAY);
		    int age=calendarToday.get(Calendar.YEAR)-calendarBirthday.get(Calendar.YEAR)-(remainingDays>0 ? 1 : 0);
		    if(remainingDays<0) {remainingDays+=DateTimeUtilities.ONEYEAR/DateTimeUtilities.ONEDAY;}
		    link.setRemainingDaysText(remainingDays+getResString(TIPS_REMAINING_DAYS));
		    link.setTitleText(_birthdayName.getText() + " (" + age + ")");
		}

		SimpleDateFormat sdfBirthday=new SimpleDateFormat(SimpleDateFormat.DATE_MEDIUM);
	    link.setDateOfBirthText(sdfBirthday.formatLocal(calendarBirthday.getTime().getTime())+lunarDay);
		
		_foreground.add(new LabelField(_birthdayDate.getDate()+"", FOCUSABLE | USE_ALL_WIDTH));
	}

	public void fieldChanged(Field field, int context)
	{
		if(field==_usingLunar)
		{
			_usingLunar.setDirty(true);
	    	clockUpdated();
		} else if(field==_birthdayDate)
		{
			_birthdayDate.setDirty(true);
	   	   	clockUpdated();
		} else if(field==_birthdayName)
		{
			clockUpdated();
		}
	}
}